/*
 * 
 * LegendShop 多用户商城系统
 * 
 *  版权所有,并保留所有权利。
 * 
 */
package com.legendshop.permission.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.legendshop.oa.constants.Constants;
import com.legendshop.oa.model.Menu;
import com.legendshop.oa.model.RoleMenu;
import com.legendshop.permission.dao.MenuManagerDao;
import com.legendshop.permission.service.MenuManagerService;
import com.legendshop.util.AppUtils;

/**
 * 菜單管理器
 */
public class MenuManagerServiceImpl implements MenuManagerService {
	
	/** The log. */
	private final Logger log = LoggerFactory.getLogger(MenuManagerServiceImpl.class);

	/** The menu dao. */
	private MenuManagerDao menuManagerDao;
	
	/**
	 * 获取允许展示的Menu
	 * 被屏蔽的Menu将不会被显示（即使拥有该菜单的访问权限也不行） 
	 */
	@Override
	public List<Menu> getMenu() {
		List<Menu> menuList = getAllMenu();
		Iterator<Menu> iter = menuList.iterator();
		while( iter.hasNext() ){
			if( Constants.OFFLINE.equals( 
				iter.next().getStatus() ))
				iter.remove();
		}
		return menuList;
	}

	/**
	 * 获取所有Menu,排除掉由不存在的Plugin提供的菜单
	 * 后台菜单管理专用
	 * */
	@Override
	public List<Menu> getAllMenu() {
		//获取所有可用的菜单
		List<Menu> menuList = menuManagerDao.getMenu();
		List<RoleMenu> thirdLevenRoleMenuList = menuManagerDao.getRoleMenu();
		
		/**
		 * 重新组装RoleMenu关系，对于菜单进行追溯
		 * ,如果第三级有访问权限，则自动给第一第二级菜单加上访问权限
		 * 如果第二级有访问权限，则自动给第一级加上访问权限
		 */
		List<RoleMenu> roleMenuList = parseRoleMenu(menuList, thirdLevenRoleMenuList);
		
		if(AppUtils.isNotBlank(menuList) && AppUtils.isNotBlank(roleMenuList)){
			for (int i = 0; i < menuList.size(); i++) {
				Menu menu = menuList.get(i);
				for (int j = 0; j < roleMenuList.size(); j++) {
					RoleMenu roleMenu = roleMenuList.get(j);
					if(menu.getMenuId().equals(roleMenu.getMenuId())){
						menu.addRequiredAnyFunctions(roleMenu.getRoleName());
					}
				}
			}
		}
		return menuList;
	}
	
	/**
	 * 重新组装RoleMenu关系，对于菜单进行追溯
	 * ,如果第三级有访问权限，则自动给第一第二级菜单加上访问权限
	 * 如果第二级有访问权限，则自动给第一级加上访问权限
	 * @param menuList
	 * @return
	 */
	private  List<RoleMenu> parseRoleMenu( List<Menu> menuList,List<RoleMenu> roleMenuList){
		 Map<Long, Menu> menuMap = new LinkedHashMap<Long, Menu>();
		 
		 for (Menu menu : menuList) {
			 menuMap.put(menu.getMenuId(), menu);
		}
		 
		 List<RoleMenu> constructRoleMenuList =  new ArrayList<RoleMenu>();
		 for(RoleMenu roleMenu : roleMenuList) {
			 constructRoleMenuList.add(roleMenu);
			 
			 Menu currentMenu = menuMap.get(roleMenu.getMenuId());
			 
			 if (currentMenu == null) {
				 if (log.isDebugEnabled()) {
					log.debug("Menu not found, may be it had been deleted or offline, MenuId：{}, Role Name is {}" , roleMenu.getMenuId(), roleMenu.getRoleName());
				}
				 continue;
			}
			 
			 Menu parentMenu = menuMap.get(currentMenu.getParentId());
			 
			 //三级追溯二级
			 if (parentMenu!=null) {
				 
				 RoleMenu parentRoleMenu = new RoleMenu();
				 parentRoleMenu.setMenuId(parentMenu.getMenuId());
				 parentRoleMenu.setRoleId(roleMenu.getRoleId());
				 parentRoleMenu.setRoleName(roleMenu.getRoleName());
				 constructRoleMenuList.add(parentRoleMenu);
				 				 
				 //二级追溯一级
				 if (parentMenu.getGrade() > 1) {
					 
					 Menu firstLevelMenu = menuMap.get(parentMenu.getParentId());

					 if (firstLevelMenu != null) {
						 RoleMenu firstlevenRoleMenu = new RoleMenu();
						 firstlevenRoleMenu.setMenuId(firstLevelMenu.getMenuId());
						 firstlevenRoleMenu.setRoleId(roleMenu.getRoleId());
						 firstlevenRoleMenu.setRoleName(roleMenu.getRoleName());
						 constructRoleMenuList.add(firstlevenRoleMenu);
						 
					}
				}
			}
			 
		 }
		 
		 
		 
		 return constructRoleMenuList;
	}
	
	
	/**
	 * 拿到Role与Menu的关系
	 * */
	public Map<String,List<Menu>> buildRoleMenu(List<Menu> menuList){
		//	这里生成的关系会被缓存到 MenuManager中
		Map<String,List<Menu>> role2menu = new HashMap<String,List<Menu>>();
		
		//List<Menu> allMenuList = menuManagerDao.getMenu();
		
		//获取每个Role所拥有的菜单的全集
		List<RoleMenu> thirdLevenRoleMenuList = menuManagerDao.getRoleMenu();
		
		/**
		 * 重新组装RoleMenu关系，对于菜单进行追溯
		 * ,如果第三级有访问权限，则自动给第一第二级菜单加上访问权限
		 * 如果第二级有访问权限，则自动给第一级加上访问权限
		 */
		List<RoleMenu> roleMenuList = parseRoleMenu(menuList, thirdLevenRoleMenuList);
		
		//以roleName为Key放置对应的菜单
		for( RoleMenu r2m : roleMenuList ){
			List<Menu> ml = role2menu.get( r2m.getRoleName());
			if( ml == null ){
				ml = new ArrayList<Menu>();
				role2menu.put( r2m.getRoleName(), ml );
			}
			for( Menu me : menuList ){
				if(me.getMenuId().equals(r2m.getMenuId())){
					ml.add(me);
					break;
				}
			}
		}
		
		return role2menu;
	}
	
	/**
	 * @param menuManagerDao the menuManagerDao to set
	 */
	public void setMenuManagerDao(MenuManagerDao menuManagerDao) {
		this.menuManagerDao = menuManagerDao;
	}

}
